package com.foreveross.crawl.common.core;

import java.io.Serializable;
import java.sql.Clob;
import java.util.List;

import javax.persistence.Basic;
import javax.persistence.Cacheable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Lob;
import javax.persistence.Table;

import org.openkoala.koala.auth.core.domain.KoalaSecurityEntity;

@Entity
@Table(name = "WEBCRAWL_TASK_MODEL")
@Cacheable
public class TaskModelEntity extends KoalaSecurityEntity {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 7520486167621574600L;
	@Column(name = "taskId")
	private String taskId;
	@Column(name = "channelId")
	private Long channelId;
	@Column(name = "channelName")
	private String channelName;
	/**
	 * 分组ID
	 */
	@Column(name = "groupId")
	private Long groupId;
	/**
	 * 分组名称
	 */
	@Column(name = "groupName")
	private String groupName;
	/**
	 * 是否使用代理IP 0不使用，1使用
	 */
	@Column(name = "isProxyIp")
	private Long isProxyIp;
	/**
	 * 请求参数集 是一串JSON数据
	 */
	@Column(name = "paramsJson")
	private String paramsJson;
	/**
	 * 描述监控页面显示的元数据
	 */
	@Column(name = "metadata")
	private String metadata;
	/**
	 * 任务开始时间
	 */
	@Column(name = "taskStartDate")
	private String taskStartDate;
	/**
	 * 任务结束时间
	 */
	@Column(name = "taskEndDate")
	private String taskEndDate;
	/**
	 * 任务执行时间
	 */
	@Column(name = "taskExcuteTotal")
	private long taskExcuteTotal;
	/**
	 * 页面编码方式 如:UTF-8等
	 */
	@Column(name = "encoded")
	private String encoded;
	
	/**
	 * 代理IP，有多个则用  ~ 进行分割
	 */
	@Column(name = "proxyIp")
	private String proxyIp;
	/**
	 * 任务发布时间
	 */
	@Column(name = "taskPublish")
	private String taskPublish;

	/**
	 * 该任务类型（如高铁类型、航空类型等等）（与任务创建时间构建成独立的数据空间）
	 * 旧版任务模型而来
	 */
	@Column(name = "taskType")
	private int taskType;
	
	/**
	 * 轨迹记录
	 */
	@Lob
	@Basic(fetch = FetchType.LAZY)
//	@Column(name = "tracks", columnDefinition = "TEXT", length = Integer.MAX_VALUE, nullable = true)
//	private String tracks;
	@Column(name = "tracks", nullable = true)
	private Clob tracks;
	
	/**
	 * 任务状态
	 */
	@Column(name = "taskState")
	private String taskState;
	
	/**
	 * 任务十分有效   0 为无效
	 * 无效的情形为：在节点启动时，发现任务中存在的非完成及非异常的任务
	 */
	@Column(name = "isVaild")
	private Long isVaild;

	public String getTaskId() {
		return taskId;
	}

	public void setTaskId(String taskId) {
		this.taskId = taskId;
	}

	public Long getChannelId() {
		return channelId;
	}

	public void setChannelId(Long channelId) {
		this.channelId = channelId;
	}

	public String getChannelName() {
		return channelName;
	}

	public void setChannelName(String channelName) {
		this.channelName = channelName;
	}

	public Long getIsProxyIp() {
		return isProxyIp;
	}

	public void setIsProxyIp(Long isProxyIp) {
		this.isProxyIp = isProxyIp;
	}

	public String getParamsJson() {
		return paramsJson;
	}

	public void setParamsJson(String paramsJson) {
		this.paramsJson = paramsJson;
	}

	public String getMetadata() {
		return metadata;
	}

	public void setMetadata(String metadata) {
		this.metadata = metadata;
	}

	public String getTaskStartDate() {
		return taskStartDate;
	}

	public void setTaskStartDate(String taskStartDate) {
		this.taskStartDate = taskStartDate;
	}

	public String getTaskEndDate() {
		return taskEndDate;
	}

	public void setTaskEndDate(String taskEndDate) {
		this.taskEndDate = taskEndDate;
	}

	public long getTaskExcuteTotal() {
		return taskExcuteTotal;
	}

	public void setTaskExcuteTotal(long taskExcuteTotal) {
		this.taskExcuteTotal = taskExcuteTotal;
	}

	public String getEncoded() {
		return encoded;
	}

	public void setEncoded(String encoded) {
		this.encoded = encoded;
	}

	public String getProxyIp() {
		return proxyIp;
	}

	public void setProxyIp(String proxyIp) {
		this.proxyIp = proxyIp;
	}

	public String getTaskPublish() {
		return taskPublish;
	}

	public void setTaskPublish(String taskPublish) {
		this.taskPublish = taskPublish;
	}

	public int getTaskType() {
		return taskType;
	}

	public void setTaskType(int taskType) {
		this.taskType = taskType;
	}

	@Override
	public String toString() {
		return "TaskModelEntity [taskId=" + taskId + ", channelId=" + channelId
				+ ", channelName=" + channelName + ", groupId=" + groupId
				+ ", groupName=" + groupName + ", isProxyIp=" + isProxyIp
				+ ", paramsJson=" + paramsJson + ", metadata=" + metadata
				+ ", taskStartDate=" + taskStartDate + ", taskEndDate="
				+ taskEndDate + ", taskExcuteTotal=" + taskExcuteTotal
				+ ", encoded=" + encoded + ", proxyIp=" + proxyIp
				+ ", taskPublish=" + taskPublish + ", taskType=" + taskType
				+ ", tracks=" + tracks + ", taskState=" + taskState
				+ ", isVaild=" + isVaild + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result
				+ ((channelId == null) ? 0 : channelId.hashCode());
		result = prime * result
				+ ((channelName == null) ? 0 : channelName.hashCode());
		result = prime * result + ((encoded == null) ? 0 : encoded.hashCode());
		result = prime * result + ((groupId == null) ? 0 : groupId.hashCode());
		result = prime * result
				+ ((groupName == null) ? 0 : groupName.hashCode());
		result = prime * result
				+ ((isProxyIp == null) ? 0 : isProxyIp.hashCode());
		result = prime * result + ((isVaild == null) ? 0 : isVaild.hashCode());
		result = prime * result
				+ ((metadata == null) ? 0 : metadata.hashCode());
		result = prime * result
				+ ((paramsJson == null) ? 0 : paramsJson.hashCode());
		result = prime * result + ((proxyIp == null) ? 0 : proxyIp.hashCode());
		result = prime * result
				+ ((taskEndDate == null) ? 0 : taskEndDate.hashCode());
		result = prime * result
				+ (int) (taskExcuteTotal ^ (taskExcuteTotal >>> 32));
		result = prime * result + ((taskId == null) ? 0 : taskId.hashCode());
		result = prime * result
				+ ((taskPublish == null) ? 0 : taskPublish.hashCode());
		result = prime * result
				+ ((taskStartDate == null) ? 0 : taskStartDate.hashCode());
		result = prime * result
				+ ((taskState == null) ? 0 : taskState.hashCode());
		result = prime * result + taskType;
		result = prime * result + ((tracks == null) ? 0 : tracks.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (getClass() != obj.getClass())
			return false;
		TaskModelEntity other = (TaskModelEntity) obj;
		if (channelId == null) {
			if (other.channelId != null)
				return false;
		} else if (!channelId.equals(other.channelId))
			return false;
		if (channelName == null) {
			if (other.channelName != null)
				return false;
		} else if (!channelName.equals(other.channelName))
			return false;
		if (encoded == null) {
			if (other.encoded != null)
				return false;
		} else if (!encoded.equals(other.encoded))
			return false;
		if (groupId == null) {
			if (other.groupId != null)
				return false;
		} else if (!groupId.equals(other.groupId))
			return false;
		if (groupName == null) {
			if (other.groupName != null)
				return false;
		} else if (!groupName.equals(other.groupName))
			return false;
		if (isProxyIp == null) {
			if (other.isProxyIp != null)
				return false;
		} else if (!isProxyIp.equals(other.isProxyIp))
			return false;
		if (isVaild == null) {
			if (other.isVaild != null)
				return false;
		} else if (!isVaild.equals(other.isVaild))
			return false;
		if (metadata == null) {
			if (other.metadata != null)
				return false;
		} else if (!metadata.equals(other.metadata))
			return false;
		if (paramsJson == null) {
			if (other.paramsJson != null)
				return false;
		} else if (!paramsJson.equals(other.paramsJson))
			return false;
		if (proxyIp == null) {
			if (other.proxyIp != null)
				return false;
		} else if (!proxyIp.equals(other.proxyIp))
			return false;
		if (taskEndDate == null) {
			if (other.taskEndDate != null)
				return false;
		} else if (!taskEndDate.equals(other.taskEndDate))
			return false;
		if (taskExcuteTotal != other.taskExcuteTotal)
			return false;
		if (taskId == null) {
			if (other.taskId != null)
				return false;
		} else if (!taskId.equals(other.taskId))
			return false;
		if (taskPublish == null) {
			if (other.taskPublish != null)
				return false;
		} else if (!taskPublish.equals(other.taskPublish))
			return false;
		if (taskStartDate == null) {
			if (other.taskStartDate != null)
				return false;
		} else if (!taskStartDate.equals(other.taskStartDate))
			return false;
		if (taskState == null) {
			if (other.taskState != null)
				return false;
		} else if (!taskState.equals(other.taskState))
			return false;
		if (taskType != other.taskType)
			return false;
		if (tracks == null) {
			if (other.tracks != null)
				return false;
		} else if (!tracks.equals(other.tracks))
			return false;
		return true;
	}
	
	public static void saveOrUpdate(TaskModelEntity taskModel){
		getRepository().save(taskModel);
	}
	
	public static <T extends org.dayatang.domain.Entity> T load(Class<T> clazz, Serializable id) {
		return getRepository().load(clazz, id);
	}
	
	public static void delete(TaskModelEntity taskModel){
		getRepository().remove(taskModel);
	}
	
	public static List<TaskModelEntity> findByTaskId(String taskId){

		String jpql = "select t from TaskModelEntity t where t.taskId =:taskId";
		return getRepository().createJpqlQuery(jpql).addParameter("taskId", taskId).list();
	}
	
	public static TaskModelEntity findNewestByTaskId(String taskId){

		String jpql = "select t from TaskModelEntity t where t.taskId =:taskId order by id desc";
		List<TaskModelEntity> entityList = getRepository().createJpqlQuery(jpql).addParameter("taskId", taskId).list();
		return (entityList != null && entityList.size() != 0) ? entityList.get(0) : null;
	}
	
	public static List<TaskModelEntity> findTaskModelByChannelIdAndState(Long channelId, String state){
		String jpql = "select t from TaskModelEntity t where t.channelId =:channelId and t.taskState =:state";
		return getRepository().createJpqlQuery(jpql).addParameter("channelId", channelId).addParameter("state", state).list();
	}
	
	/**  
	 * @Description: 删除无效的任务信息，即不是执行完成或异常的任务信息
	 * @author luofangyi
	 * @date 2014-10-11 上午9:40:33 
	 */ 
	public static void deleteTaskModelForValid(){
		String jpql = "delete from TaskModelEntity where taskState not in ('FINISHED','EXCEPTION')";
		getRepository().createJpqlQuery(jpql).executeUpdate();
	}
	
	public static void deleteAll(){
		String jpql = "delete from TaskModelEntity";
		getRepository().createJpqlQuery(jpql).executeUpdate();
	}
	
	public static int countTaskModel(){
		String jpql = "select t from TaskModelEntity t";
		List<TaskModelEntity> entityList = getRepository().createJpqlQuery(jpql).list();
		return entityList != null ? entityList.size() : 0;
	}
	
	public static int countTaskModelOfSuccess(Long channelId){
		String jpql = "select t from TaskModelEntity t where t.taskState = 'FINISHED' and channelId =:channelId";
		List<TaskModelEntity> entityList = getRepository().createJpqlQuery(jpql).addParameter("channelId", channelId).list();
		return entityList != null ? entityList.size() : 0;
	}
	
	public static int countTaskModelOfFail(Long channelId){
		String jpql = "select t from TaskModelEntity t where t.taskState = 'EXCEPTION' and channelId =:channelId";
		List<TaskModelEntity> entityList = getRepository().createJpqlQuery(jpql).addParameter("channelId", channelId).list();
		return entityList != null ? entityList.size() : 0;
	}
	
	public static int countTaskModelOfDoing(Long channelId){
		String jpql = "select t from TaskModelEntity t where t.taskState = 'DOING' and channelId =:channelId";
		List<TaskModelEntity> entityList = getRepository().createJpqlQuery(jpql).addParameter("channelId", channelId).list();
		return entityList != null ? entityList.size() : 0;
	}

	public Clob getTracks() {
		return tracks;
	}

	public void setTracks(Clob tracks) {
		this.tracks = tracks;
	}

	public String getTaskState() {
		return taskState;
	}

	public void setTaskState(String taskState) {
		this.taskState = taskState;
	}

	@Override
	public String[] businessKeys() {
		
		return new String[] { String.valueOf(getId()), this.getChannelName(),
				this.getTaskStartDate() };
	}

	public Long getGroupId() {
		return groupId;
	}

	public void setGroupId(Long groupId) {
		this.groupId = groupId;
	}

	public String getGroupName() {
		return groupName;
	}

	public void setGroupName(String groupName) {
		this.groupName = groupName;
	}

	public Long getIsVaild() {
		return isVaild;
	}

	public void setIsVaild(Long isVaild) {
		this.isVaild = isVaild;
	}
}
